﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Xml.Serialization;
using System.Xml;
using System.Linq.Expressions;
namespace FinosLibrary {
    public static class XMLSer {
        public static string ToXML(this object item) {
            XmlSerializer ser = new XmlSerializer(item.GetType());
            string s;
            using (MemoryStream ms = new MemoryStream()) {
                ser.Serialize(ms, item);
                ms.Seek(0, SeekOrigin.Begin);
                using (StreamReader sr = new StreamReader(ms)) {
                    s = sr.ReadToEnd();
                }
            }
            return s;
        }
        public static T FromXML<T>(this string xml) {
            XmlSerializer ser = new XmlSerializer(typeof(T));
            T o;
            using(MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))){
                o = (T)ser.Deserialize(ms);
            }
            return o;
        }
        public static T FromXML<T>(this XmlReader xml) {
            XmlSerializer ser = new XmlSerializer(typeof(T));
            T o = (T)ser.Deserialize(xml);
            xml.Close();
            return o;
        }
        public static T FromXML<T>(this Stream xml) {
            XmlSerializer ser = new XmlSerializer(typeof(T));
            T o = (T)ser.Deserialize(xml);
            xml.Close();
            return o;
        }
    }
    public static class Json {
        public static string ToJson(this object item) {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType());
            using (MemoryStream ms = new MemoryStream()) {
                serializer.WriteObject(ms, item);
                byte[] bytes = ms.ToArray();
                return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
            }
        }
        public static byte[] ToJsonBytes(this object item) {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType());
            using (MemoryStream ms = new MemoryStream()) {
                serializer.WriteObject(ms, item);
                return ms.ToArray();
            }
        }
        public static T FromJsonTo<T>(this string jsonString) {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            T jsonObject;
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))) {
                jsonObject = (T)ser.ReadObject(ms);
            }
            return jsonObject;
        }
        public static T FromJsonTo<T>(this MemoryStream ms) {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            T jsonObject = (T)ser.ReadObject(ms);
            ms.Close();
            return jsonObject;
        }
        public static T FromJsonTo<T>(this byte[] bytes) {
            return FromJsonTo<T>(new MemoryStream(bytes));
        }
    }
    public static class GetInstanceClass {
        public static List<object> list = new List<object>();
        public static object GetInstance(this Type t,object[] arg) {
            var ls = list.Where(x => x.GetType() == t);
            object l;
            if (ls.Count() == 0) {
                l = Activator.CreateInstance(t, arg);
                list.Add(l);
            } else {
                l = ls.First();
            }
            return l;
        }
        
        public static T GetInstance<T>(this object obj,params object[] arg) {
            var ls = list.Where(x => x.GetType() == typeof(T));
            object l;
            if (ls.Count() == 0) {
                l = Activator.CreateInstance(typeof(T), arg);
                list.Add(l);
            } else {
                l = ls.First();
            }
            return (T)l;
        }
    }
    public static class PropertyChangedBaseEx {
        public static void NotifyPropertyChanged<T, TProperty>(this　T propertyChangedBase, Expression<Func<T, TProperty>> expression) where T : NotifyProperty {
            var memberExpression = expression.Body as MemberExpression;
            if (memberExpression != null) {
                string propertyName = memberExpression.Member.Name;
                propertyChangedBase._NotifyPropertyChanged(propertyName);
            } else
                throw new NotImplementedException();
        }
    }
}
